Skip to content

Conversation

@enmande
Copy link
Contributor

@enmande enmande commented Jan 2, 2026

🎟️ Tracking

PM-29584

📔 Objective

Adds an email template and view for sending notifications to users that one or more of their emergency contacts (Emergency Access user feature grantees) has been removed.

Includes HTML and text-only email templates with unit tests to illustrate instantiation and consumption with the newer IMailer strategy (not the legacy Handlebars mailer service).

🥇 Bonus: moves EmergencyAccess into the UserFeatures space. As I understand, this has been a desired relocation to align with other Auth architecture. The positioning of the mail templates also mirrors this move to set up future feature-scoped development.

📸 Screenshots

HTML: Single contact removed

PM-29584__single-html

HTML: Multiple contacts removed

PM-29584__multi__html

Text

PM-29584__multi-text

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 2026

Logo
Checkmarx One – Scan Summary & Detailsbe1d05ef-3d60-4bae-9323-daf18ebedc67

New Issues (2)

Checkmarx found the following issues in this Pull Request

# Severity Issue Source File / Package Checkmarx Insight
1 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 123
detailsMethod at line 123 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from request. Thi...
Attack Vector
2 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 452
detailsMethod at line 452 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector

@codecov
Copy link

codecov bot commented Jan 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 55.94%. Comparing base (d1fdaa6) to head (d02f324).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6793      +/-   ##
==========================================
- Coverage   55.95%   55.94%   -0.02%     
==========================================
  Files        1964     1965       +1     
  Lines       86791    86794       +3     
  Branches     7729     7729              
==========================================
- Hits        48567    48560       -7     
- Misses      36425    36435      +10     
  Partials     1799     1799              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@enmande enmande added the ai-review Request a Claude code review label Jan 2, 2026
@enmande enmande added ai-review Request a Claude code review and removed ai-review Request a Claude code review labels Jan 9, 2026
@claude
Copy link
Contributor

claude bot commented Jan 9, 2026

Claude finished @enmande's task in 2m 47s —— View job


Code Review Summary

Overview

PR #6793 adds email template infrastructure for notifying users when emergency access grantees are removed, and relocates EmergencyAccess services to the UserFeatures namespace.

Assessment: ✅ APPROVED

This PR demonstrates excellent code quality with comprehensive test coverage and follows established Bitwarden patterns.


Changes Reviewed

New Email Template System

  • EmergencyAccessRemoveGranteesMailView.cs - Mail view model with required grantee names
  • .html.hbs and .text.hbs templates - HTML and plain text email formats
  • .mjml source file - MJML template for email generation
  • EmergencyAccessMailTests.cs - Comprehensive test suite demonstrating usage

Namespace Refactoring

  • Moved EmergencyAccessService and IEmergencyAccessService from Core.Auth.Services to Core.Auth.UserFeatures.EmergencyAccess
  • Updated all references in controllers, jobs, and tests
  • Updated DI registration in ServiceCollectionExtensions.cs

Security Analysis ✅

  • No security concerns identified
  • Email contains only grantee names (non-sensitive, already accessible to grantor)
  • No authentication/authorization changes
  • Follows established mail delivery patterns
  • No PII or sensitive data exposure

Correctness ✅

  • No logic errors found
  • Namespace migrations are mechanically correct and consistent
  • RemovedGranteeNames uses required keyword preventing null issues
  • Email templates properly escape Handlebars variables
  • Return type changes (Entities.EmergencyAccess fully qualified) maintain clarity

Breaking Changes ✅

  • No breaking changes
  • Namespace change is internal refactoring only
  • Interface signatures unchanged (same contract, different namespace)
  • DI registration maintains service compatibility

Test Coverage ✅

  • Excellent test coverage
  • Tests demonstrate email construction with IMailer
  • Validates single and multiple grantee scenarios
  • Confirms subject line and help URL constants
  • Verifies HTML and text content rendering
  • Tests serve as documentation for future usage

Code Quality ✅

  • Follows established BaseMail<T> and BaseMailView patterns
  • Clean separation of concerns
  • Appropriate use of required keyword for mandatory properties
  • Template location mirrors namespace structure
  • Well-documented through tests and README

Developer Response to Previous Review

The developer appropriately addressed prior suggestions:

  • Subject mutability: Correctly explained that { get; set; } is required to match base class signature (cannot use init)
  • Empty collection validation: Correctly noted that required prevents instantiation without a collection, and validation should occur at the caller level (command), not in the presentational view

Notes

  1. Email Template Infrastructure: This PR adds the template and view classes but does not yet integrate email sending into the service layer. The comprehensive tests demonstrate the intended usage pattern for when a command/service method is added to actually send the email.

  2. Namespace Architecture Alignment: The move to Auth.UserFeatures.EmergencyAccess aligns with Bitwarden's architectural direction and improves organization.

  3. Generated HTML: The 498-line .html.hbs file is compiled from the 31-line .mjml source, which is a standard email template generation practice.


Recommendation

APPROVE - This PR is ready to merge. The code is well-architected, thoroughly tested, and follows Bitwarden security and quality standards.


Review completed: All critical areas examined

  • ✅ Security (authentication, authorization, data exposure)
  • ✅ Correctness (logic, null handling, edge cases)
  • ✅ Breaking changes
  • ✅ Performance
  • ✅ Test coverage
  • ✅ Maintainability

Reviewed by Claude Code (Bitwarden Code Review Agent)

@enmande
Copy link
Contributor Author

enmande commented Jan 12, 2026

Re: Claude comments:

🎨 Minor Improvements (2)

  1. Mutable Subject Property

    • File: src/Core/Auth/UserFeatures/EmergencyAccess/Mail/EmergencyAccessRemoveGranteesMailView.cs:13
    • Issue: The Subject property has a public setter, allowing modification after initialization
    • Suggestion: Consider making it init-only for immutability:
    public override string Subject { get; init; } = "Emergency contacts removed";
    • Impact: Low - currently no code path modifies it, but immutability would prevent future bugs

Overriding Subject requires signature matching (i.e., get and set accessors, not get and init). This might be a handy update to the inherited, but out of scope here.

  1. Empty Collection Handling

    • Context: The email template doesn't validate that RemovedGranteeNames contains at least one item
    • Suggestion: Consider adding validation in the mail view or documenting the expectation that callers must ensure non-empty collections
    • Impact: Low - tests show proper usage, but defensive validation would prevent edge cases

RemovedGranteeNames is a required field. The view cannot be instantiated without a collection. Yes that means the collection can be empty. However, for keeping the template presentational, this should not fall to the template to enforce; it should be interrogated/handled at view creation time in the caller (command).

@enmande enmande marked this pull request as ready for review January 12, 2026 16:29
@enmande enmande requested a review from a team as a code owner January 12, 2026 16:29
ike-kottlowski
ike-kottlowski previously approved these changes Jan 13, 2026
@enmande enmande added needs-qa and removed ai-review Request a Claude code review labels Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants